﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using VM.Core;
using VM.PlatformSDKCS;
using VMControls.Interface;
using VMControls.RenderInterface;
using VMControls.Winform.Release;
using Mvvm.Commands;
using GlobalCameraModuleCs;
using ImageSourceModuleCs;
using IMVSCircleFindModuCs;
using IMVSLineFindModuCs;
using IMVSCaliperCornerModuCs;
using IMVSFastFeatureMatchModuCs;
using IMVSHPFeatureMatchModuCs;
using VisionDesigner;
using VisionDesigner.HPFeaturePatMatch;
using VisionDesigner.FastFeaturePatMatch;

using Vision.src;
using Vision.roi;
using Vision.page;


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

using VisionDesigner;
using VisionDesigner.FastFeaturePatMatch;
using MvdXmlParse;

namespace Vision
{
    public partial class Form1 : Form
    {
        public static Form1 MyForm;
        public static CircleFind circleFind = new CircleFind();
        public static LineFind lineFind = new LineFind();
        public static CaliperCorner caliperCorner = new CaliperCorner();

        private roi.roi ROI = new roi.roi();

        bool mSolutionIsLoad = false;  //true 代表方案加载成功，false 代表方案关闭
        private string ModuleName = ""; // 模块实际名称
        public string ModuleProcessName = "流程1";
        public string ModuleNameDefault = "流程1.图像源"; // 模块默认名称
        private List<IROI> roiList = new List<IROI>(); // 多ROI List
        private CMvdImage cInputImg = new CMvdImage();

        public string filename = "E:\\点胶项目\\Vision\\images\\result.jpg";

        private string modelExportPath = string.Empty; // 模型另存为导出路径
        private string modelExportPathDefault = "HPPattern.hpmxml"; // 模型导出默认路径
        private string[] modelExportPathList = new string[1]; // 本示例只有一个模型文件，所以数组长度设为1

        /// <summary>
        /// 快速模板算子
        /// </summary>
        private CFastFeaturePattern _FastFeaturePattern = null;

        /// <summary>
        /// 快速匹配Tool算子
        /// </summary>
        private CFastFeaturePatMatchTool _FastFeaturePatMatchTool = null;

        /// <summary>
        /// 输入图像
        /// </summary>
        private CMvdImage _InputImage = null;

        /// <summary>
        /// ROI
        /// </summary>
        private CMvdShape _ROIShape = null;





        public Form1()
        {
            InitializeComponent();
        }

        private void buttonImplement_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "VM Sol File|*.sol*";
            DialogResult openFileRes = openFileDialog.ShowDialog();
            if (DialogResult.OK == openFileRes)
            {
                textBox1.Text = openFileDialog.FileName;
            }
            UpdateListBox("选择路径成功");

            try
            {
                // 加载方案
                VmSolution.Load(textBox1.Text);
                mSolutionIsLoad = true;
                // 添加成功消息到列表框
                UpdateListBox("方案加载成功");

                //VmSolution.Instance.SyncRun();

                IVmModule vmModule = (IVmModule)VmSolution.Instance[ModuleNameDefault];
                vmRenderControl1.ModuleSource = vmModule;

                //VmProcedure process = (VmProcedure)VmSolution.Instance[ModuleProcessName];
                //if (null == process) return;
                //vmRenderControl1.ModuleSource = process;
                //process.Run();

            }
            catch (Exception ex)
            {
                // 记录异常信息或通知用户
                UpdateListBox("加载方案时出错：" + ex.Message);
            }
        }

        public void UpdateListBox(string message)
        {
            if (listBoxMsg.InvokeRequired)
            {
                // 如果当前线程不是 UI 线程，则通过 Invoke 方法调用 UpdateListBox
                listBoxMsg.Invoke(new Action<string>(UpdateListBox), message);
            }
            else
            {
                // 在 UI 线程上更新 listBoxMsg
                listBoxMsg.Items.Add(message);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
            }
        }

        private void ParameterConfiguration_Click(object sender, EventArgs e)
        {
            try
            {
                VmModule module = (VmModule)VmSolution.Instance[ModuleProcessName + "." + combo_Module.Text];

                //vmprocedure vmprocess = (vmprocedure)vmsolution.instance["流程1"];
                //vmrendercontrol1.modulesource = vmprocess;
                //vmsolution.instance.syncrun();
            }
            catch (VmException ex)
            {
                UpdateListBox(Convert.ToString(ex.errorCode, 16));
            }
        }

        private void ProgrammeImplementationOnce_Click(object sender, EventArgs e)
        {
            SchemeRun();
        }

        private void SchemeRun()
        {
            string strMsg = null;

            try
            {
                VmProcedure process = (VmProcedure)VmSolution.Instance[ModuleProcessName];

                if (combo_Module.InvokeRequired)
                {
                    ModuleName = (string)combo_Module.Invoke(new Func<string>(() => ModuleProcessName + "." + combo_Module.Text));
                    if (ModuleName == ModuleProcessName + ".")
                    {
                        ModuleName = ModuleNameDefault;
                    }

                    combo_Module.BeginInvoke(new Action(() =>
                    {
                        vmRenderControl1.ModuleSource = (IVmModule)VmSolution.Instance[ModuleName];
                        vmRenderControl1.UpdateVMResultShow();
                    }));
                }
                else
                {
                    ModuleName = ModuleProcessName + "." + combo_Module.Text;
                    if (ModuleName == ModuleProcessName + ".")
                    {
                        ModuleName = ModuleNameDefault;
                    }
                    vmRenderControl1.ModuleSource = (IVmModule)VmSolution.Instance[ModuleName];
                    vmRenderControl1.UpdateVMResultShow();
                }

                if (null == process) return;
                process.Run();

                //vmRenderControl1.SaveRenderedImage(filename);
                vmRenderControl1.BringToFront();


                UpdateListBox("运行一次成功");
                if (InvokeRequired)
                {
                    Invoke(new Action(EventBinding));
                }
                else
                {
                    EventBinding();
                }
            }
            catch (VmException ex)
            {
                strMsg = "ExecuteOnce failed. Error Code: " + Convert.ToString(ex.errorCode, 16);
                UpdateListBox(strMsg);
                return;
            }
        }

        private void EventBinding()
        {
            switch (combo_Module.Text)
            {
                case "圆查找":
                {
                        IMVSCircleFindModuTool circleFindModule = (IMVSCircleFindModuTool)VmSolution.Instance[ModuleProcessName +"."+ combo_Module.Text];
                        if (null == circleFindModule)
                        {
                            UpdateListBox("未找到圆查找节点");
                            return;
                        }

                        var centerX = circleFindModule.ModuResult.OutputCircle.CenterPoint.X;
                        var centerY = circleFindModule.ModuResult.OutputCircle.CenterPoint.Y;
                        var nModuleStatus = (VmSolution.Instance[ModuleProcessName + "." + combo_Module.Text + ".Outputs.ModuStatus.Value"] as Array)?.GetValue(0);

                        if (Convert.ToString(nModuleStatus) == "0")
                        {
                            UpdateListBox("Convert.ToString(nModuleStatus) == 0 ");
                            return;
                        }

                        string strMsg = null;
                        strMsg = "ExecuteOnce success";
                        UpdateListBox(strMsg);

                        strMsg = "ModuleStatus: " + Convert.ToString(nModuleStatus);
                        UpdateListBox(strMsg);
                        strMsg = "CenterX: " + Convert.ToString(centerX);
                        UpdateListBox(strMsg);
                        strMsg = "CenterY: " + Convert.ToString(centerY);
                        UpdateListBox(strMsg);

                        circleFind.ReturnResult(new CircleFindEventArgs(centerX, centerY));
                        break;
                }
                case "直线查找":
                {
                    IMVSLineFindModuTool lineFindModule = (IMVSLineFindModuTool)VmSolution.Instance["流程1." + combo_Module.Text];
                    if (null == lineFindModule)
                    {
                        UpdateListBox("未找到直线查找节点");
                        return;
                    }
                    var startpointX = lineFindModule.ModuResult.OutputLine.StartPoint.X;
                    var startpointY = lineFindModule.ModuResult.OutputLine.StartPoint.Y;
                    var endpointX = lineFindModule.ModuResult.OutputLine.EndPoint.X;
                    var endpointY = lineFindModule.ModuResult.OutputLine.EndPoint.Y;
                    var lineangle = lineFindModule.ModuResult.LineAngle;

                    var nModuleStatus = (VmSolution.Instance[ModuleProcessName + "." + combo_Module.Text + ".Outputs.ModuStatus.Value"] as Array)?.GetValue(0);
                    if (Convert.ToString(nModuleStatus) == "0") return;

                    string strMsg = null;
                    strMsg = "ExecuteOnce success";
                    UpdateListBox(strMsg);

                    strMsg = "ModuleStatus: " + Convert.ToString(nModuleStatus);
                    UpdateListBox(strMsg);
                    strMsg = "StartPointX: " + Convert.ToString(startpointX);
                    UpdateListBox(strMsg);
                    strMsg = "StartPointY: " + Convert.ToString(startpointY);
                    UpdateListBox(strMsg);
                    strMsg = "EndPointX: " + Convert.ToString(endpointX);
                    UpdateListBox(strMsg);
                    strMsg = "EndPointY: " + Convert.ToString(endpointY);
                    UpdateListBox(strMsg);
                    strMsg = "LineAngle: " + Convert.ToString(lineangle);
                    UpdateListBox(strMsg);

                    lineFind.ReturnResult(new LineFindEventArgs(startpointX, startpointY, endpointX, endpointY, lineangle));
                    break;
                }
                case "边缘交点":
                {

                    IMVSCaliperCornerModuTool caliperCornerModule = (IMVSCaliperCornerModuTool)VmSolution.Instance["流程1." + combo_Module.Text];
                    if (null == caliperCornerModule)
                    {
                        UpdateListBox("未找到边缘交点节点");
                        return;
                    }

                    var caliperCornerX = caliperCornerModule.ModuResult.CaliperCorner.X;
                    var caliperCornerY = caliperCornerModule.ModuResult.CaliperCorner.Y;

                    var nModuleStatus = (VmSolution.Instance[ModuleProcessName + "." + combo_Module.Text + ".Outputs.ModuStatus.Value"] as Array)?.GetValue(0);
                    if (Convert.ToString(nModuleStatus) == "0") return;

                    string strMsg = null;
                    strMsg = "ExecuteOnce success";
                    UpdateListBox(strMsg);

                    strMsg = "ModuleStatus: " + Convert.ToString(nModuleStatus);
                    UpdateListBox(strMsg);
                    strMsg = "CaliperCornerX: " + Convert.ToString(caliperCornerX);
                    UpdateListBox(strMsg);
                    strMsg = "CaliperCornerY: " + Convert.ToString(caliperCornerY);
                    UpdateListBox(strMsg);
                    caliperCorner.ReturnResult(new CaliperCornerEventArgs(caliperCornerX, caliperCornerY));
                    break;
                }
                case "快速匹配":
                {
                        IMVSFastFeatureMatchModuTool fastFeatureMatchModule = (IMVSFastFeatureMatchModuTool)VmSolution.Instance["流程1." + combo_Module.Text];
                        
                        break;
                }
                default:
                {
                    break;
                }

            }
        }

        private bool RunFlag = false;
        private System.Timers.Timer runTimer = new System.Timers.Timer();
        private void RunTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            SchemeRun();
        }

        private void ContinuousExecutionButton_Click(object sender, EventArgs e)
        {
            RunFlag = !RunFlag;

            if (RunFlag)
            {
                ContinuousExecutionButton.Text = "结束";
                runTimer.Interval = 2000; // 设置定时器间隔为2000毫秒（2秒）
                runTimer.Elapsed += RunTimer_Elapsed;
                runTimer.Start();
            }
            else
            {
                ContinuousExecutionButton.Text = "开始";
                runTimer.Stop();
                runTimer.Elapsed -= RunTimer_Elapsed;
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button_Roi_Click(object sender, EventArgs e)
        {
            try
            {
                string strMsg = "";
                if (button_Roi.Text == "开启ROI绘制")
                {
                    IVmModule vmModule = (IVmModule)VmSolution.Instance[ModuleNameDefault];
                    vmRenderControl1.ModuleSource = vmModule;

                    vmRenderControl1.IsShowCustomROIMenu = true;
                    vmRenderControl1.OnCustomRoiAddEvent -= VmRenderControl1_OnCustomRoiAddEvent;
                    vmRenderControl1.OnCustomRoiAddEvent += VmRenderControl1_OnCustomRoiAddEvent;
                    button_Roi.Text = "关闭ROI绘制";
                    strMsg = "Start Draw Custom ROI";
                    UpdateListBox(strMsg);
                }
                else if (button_Roi.Text == "关闭ROI绘制")
                {
                    vmRenderControl1.IsShowCustomROIMenu = false;
                    vmRenderControl1.OnCustomRoiAddEvent -= VmRenderControl1_OnCustomRoiAddEvent;
                    button_Roi.Text = "开启ROI绘制";
                    strMsg = "Stop Draw Custom ROI";
                    UpdateListBox(strMsg);
                }
            }
            catch (VmException ex)
            {
                string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
                UpdateListBox(strMsg);
            }
            catch (Exception ex)
            {
                string strMsg = Convert.ToString(ex);
                UpdateListBox(strMsg);
            }
        }

        public void VmRenderControl1_OnCustomRoiAddEvent(object sender, CustomRoiEventArgs e)
        {

            try
            {
                string strMsg = "";

                if (!checkBox_IsMultiRoi.Checked)
                {
                    roiList.Clear();
                }

                roiList.Add(e.Roi);
                roiList.ElementAt(roiList.Count - 1).DataChangedCommand = new DelegateCommand<IROI>(OnDataChangedCommandExcute);

                ModuleName = ModuleProcessName + "." + combo_Module.Text;
                //设置ROI
                SetROI(ModuleName);

            
                //模块执行
                VmModule module = (VmModule)VmSolution.Instance[ModuleName];
                vmRenderControl1.ModuleSource = module;
                module.Run();
                strMsg = "模块执行成功";
                UpdateListBox(strMsg);

            }
            catch (MvdException ex)
            {
                string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
                UpdateListBox(strMsg);
            }
            catch (VmException ex)
            {
                string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
                UpdateListBox(strMsg);
            }
            catch (Exception ex)
            {
                string strMsg = Convert.ToString(ex);
                UpdateListBox(strMsg);
            }

        }

        /// <summary>
        /// ROI改变事件
        /// </summary>
        /// <param name="obj"></param>
        private void OnDataChangedCommandExcute(IROI obj)
        {
            try
            {
                string strMsg = "";
                //如果多ROI则根据hashCode判断改变的是哪一个ROI
                if (checkBox_IsMultiRoi.Checked)
                {
                    int index = 0, indexSame = -1;
                    foreach (var item in roiList)
                    {
                        if (obj.GetHashCode() == item.GetHashCode())
                        {
                            indexSame = index;
                        }
                        index++;
                    }
                    if (indexSame != -1)
                    {
                        roiList.RemoveAt(indexSame);
                        roiList.Add(obj);
                    }
                }
                else
                {
                    roiList.Clear();
                    roiList.Add(obj);
                }

                this.richTextBox1.Text += roiList.Count.ToString() + "\n";

                ModuleName = ModuleProcessName + "." + combo_Module.Text;
                //设置ROI
                SetROI(ModuleName);
                ////建模
                //if (checkBox_IsCreateModel.Checked)
                //    button_CreatTemplate_Click(this, null);
                ////模块执行
                VmModule module = (VmModule)VmSolution.Instance[ModuleName];
                vmRenderControl1.ModuleSource = module;
                module.Run();

            }
            catch (MvdException ex)
            {
                string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
                UpdateListBox(strMsg);
            }
            catch (VmException ex)
            {
                string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
                UpdateListBox(strMsg);
            }
            catch (Exception ex)
            {
                string strMsg = Convert.ToString(ex);
                UpdateListBox(strMsg);
            }
        }

        /// <summary>
        /// 设置ROI
        /// </summary>
        /// <returns></returns>
        public int SetROI(string moduleName)
        {
            try
            {
                string strMsg = "";

                if (checkBox_IsMultiRoi.Checked)
                {
                    ROI.SetMultiROI(roiList, moduleName);
                    strMsg = "设置多个ROI成功";
                }
                else
                {
                    this.richTextBox1.Text += roiList.ElementAt(0).ToString() + "\n";
                    if (roiList.ElementAt(0) is IRectROI rect)
                    {
                        ROI.SetRectROI(rect, moduleName);
                    }
                    else if (roiList.ElementAt(0) is ICircleROI circle)
                    {
                        ROI.SetCircleROI(circle, moduleName);
                    }
                    else if (roiList.ElementAt(0) is ISectorROI sector)
                    {
                        strMsg = "不支持此ROI \n";
                        UpdateListBox(strMsg);
                        return 0;
                    }
                    else if (roiList.ElementAt(0) is IPolygonROI polygon)
                    {
                        ROI.SetPolygonROI(polygon, moduleName);
                    }
                    else if (roiList.ElementAt(0) is ILineCaliperROI lineCaliper)
                    {
                        ROI.SetLineCaliperROI(lineCaliper, moduleName);
                    }
                    else if (roiList.ElementAt(0) is ICircleCaliperROI circleCaliper)
                    {
                        ROI.SetCircleCaliperROI(circleCaliper, moduleName);
                    }
                    else if (roiList.ElementAt(0) is ISectorCaliperROI sectorCaliper)
                    {
                        ROI.SetSectorCaliperROI(sectorCaliper, moduleName);
                    }
                    strMsg = "设置单个ROI成功";
                }
                UpdateListBox(strMsg);
            }
            catch (MvdException ex)
            {
                string strMsg = "ErrorCode: 0x" + ex.ErrorCode.ToString("X") + ", message is : " + ex.Message + "\r\n";
                UpdateListBox(strMsg);
                return 0;
            }
            catch (VmException ex)
            {
                string strMsg = "ErrorMessage is " + ex.errorMessage + " ErrorCode is " + Convert.ToString(ex.errorCode, 16);
                UpdateListBox(strMsg);
                return 0;
            }
            catch (Exception ex)
            {
                string strMsg = Convert.ToString(ex);
                UpdateListBox(strMsg);
                return 0;
            }
            return 1;
        }

        private void combo_Module_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

        private void combo_Module_DropDown(object sender, EventArgs e)
        {
            // 流程模块列表
            try
            {
                VmProcedure vmProcess = (VmProcedure)VmSolution.Instance[ModuleProcessName];
                combo_Module.Items.Clear();
                ModuleInfoList ModuList = vmProcess.GetAllModuleList();
                for (int item = 0; item < ModuList.nNum; item++)
                {
                    combo_Module.Items.Add(ModuList.astModuleInfo[item].strDisplayName);
                }
            }
            catch (VmException ex)
            {
                UpdateListBox(Convert.ToString(ex.errorCode, 16));
            }
        }

        /// <summary>
        /// 切换参数配置页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                tabPageParamConfig.Controls.Clear();
                if (combo_Module.Text == "")
                {
                    return;
                }
                ModuleName = ModuleProcessName + "." + combo_Module.Text;
                IVmModule imodule = (IVmModule)VmSolution.Instance[ModuleName];
                this.richTextBox1.Text += imodule.ModuleTypeName.ToString() + "\n";
                if ("IMVSCircleFindModu" == imodule.ModuleTypeName)
                {
                    CircleFindControl circleFindControl = new CircleFindControl(ModuleName);
                    circleFindControl.Dock = DockStyle.Fill;
                    tabPageParamConfig.Controls.Clear();
                    tabPageParamConfig.Controls.Add(circleFindControl);
                }
                else if ("ImageSourceModule" == imodule.ModuleTypeName)
                {
                    CameraControl cameraControl = new CameraControl(ModuleName);
                    cameraControl.Dock = DockStyle.Fill;
                    tabPageParamConfig.Controls.Clear();
                    tabPageParamConfig.Controls.Add(cameraControl);
                }
                else if ("IMVSFastFeatureMatchModu" == imodule.ModuleTypeName)
                {
                    FastFeaturePatMatchControl fastFeaturePatMatchControl = new FastFeaturePatMatchControl(ModuleName);
                    fastFeaturePatMatchControl.Dock = DockStyle.Fill;
                    tabPageParamConfig.Controls.Clear();
                    tabPageParamConfig.Controls.Add(fastFeaturePatMatchControl);
                }
                else if ("IMVSHPFeatureMatchModu" == imodule.ModuleTypeName)
                {
                    HPFeatureMatchControl hPFeatureMatchControl = new HPFeatureMatchControl(ModuleName);
                    hPFeatureMatchControl.Dock = DockStyle.Fill;
                    tabPageParamConfig.Controls.Clear();
                    tabPageParamConfig.Controls.Add(hPFeatureMatchControl);
                }
            }
            catch (VmException ex)
            {
                string strMsg = ex.errorMessage + "ErrorCode is " + ex.errorCode.ToString();
                this.richTextBox1.Text += strMsg;
            }
            catch (Exception ex)
            {
                string strMsg = Convert.ToString(ex);
                this.richTextBox1.Text += strMsg;
            }
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void buttonSaveSolution_Click(object sender, EventArgs e)
        {
            string strMsg = null;

            if (mSolutionIsLoad == true)
            {
                try
                {
                    this.Enabled = false;
                    VmSolution.Save();
                }
                catch (VmException ex)
                {
                    strMsg = "SaveSolution failed. Error Code: " + Convert.ToString(ex.errorCode, 16) + "\n";
                    this.richTextBox1.Text += strMsg;
                    return;
                }
                finally
                {
                    this.Enabled = true;
                }

                strMsg = "SaveSolution success\n";
                this.richTextBox1.Text += strMsg;
            }
            else
            {
                strMsg = "No solution file.\n";
                this.richTextBox1.Text += strMsg;
            }
        }



        public void SetLabelText(string text)
        {
            this.richTextBox1.Text += text;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "JPEG Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif|PNG Image|*.png";
                saveFileDialog.Title = "Save an Image File";

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        // 获取文件路径
                        string filePath = saveFileDialog.FileName;
                        vmRenderControl1.SaveRenderedImage(filePath);
                        this.richTextBox1.Text += "Image saved to [" + filePath + "].\r\n";
                    }
                    catch (Exception ex)
                    {
                        this.richTextBox1.Text += "Failed to save image. Error: " + ex.Message + "\r\n";
                    }
                }
            }
        }
    }
}

